Okay.
In this lecture, we're going to expand our knowledge of client to server communication by using remote
events and remote functions.
A remote event is an instance in our game that allows the client to communicate to the server, or it
allows the server to communicate to the client.
A remote event can have a function called upon it, which is either a fire server or fire client, which
triggers an event on either the client or the server.
Any scripts in our game that are listening to those events get executed, and they can also be passed
information from our client or from the server.
So I'm going to create a new remote event inside of our replicated storage.
That way both the client and the server can access it.
And we're just going to add in here a new remote event.
And I'm not going to change the name, I'm just going to leave it at Remote Event for now.
And then I'm going to create a new server script in our server script service, and then a new local
script inside of the starter player scripts.
And to demonstrate this client to server communication, we're going to make a reference to our remote
event by first getting the service that it's stored in, which is replicated storage.
So I'm going to call this variable replicated Storage.
And that's equal to game.
And we're going to get the service replicated storage.
And then we can copy this and do the exact same thing for our server script.
And then inside of replicated storage we need to access that remote event.
So I'll create a variable for it.
I'll just call it event.
And that's equal to replicated storage dot remote event.
And again we can copy this and do the exact same thing on the server.
And what I want to do on the client is I want to refer to my event, and I want to use a function called
Fire Server.
And what this function does is it allows us to trigger the event on the server, which is the on server
event, and pass any additional information we would like to the server.
So inside these two parentheses is where we can pass information such as strings, numbers, other instances
and things like that.
So for demonstration's sake I'm just going to pass a string that says hello.
And then on the server script, what we're going to do is we're going to listen to that event.
So we're going to refer to our remote event and then index it and get the on server event.
So this event gets fired for our server scripts.
And then we need to connect a function to this remote event.
So we're going to connect and create a new lambda function or a function that has no identifier.
And what gets passed to this function is first off it's going to tell us the player that fired this
event, it's always going to be the first thing passed to this function.
We're going to get a player instance.
And this is the player who triggered the event.
After the player, we can get all of the other information that gets passed to our function.
So in this case we were expecting a string.
So we can just call this parameter here example string.
And then we can go ahead and print out the result inside of the console.
And what I'm going to do is I'm going to print out the player's name.
And then I'm also going to print out whatever they pass to the server.
In this case that's our example string.
So now when I go and run the game, we refer to the exact same event, and then we fire to the server
to trigger the on server event and we pass the information of hello.
So that means when this event gets triggered this function is going to execute.
It's going to tell us the player that triggered this event.
And then it's going to also pass whatever information the client passed to the server.
In this case that is our string.
So if we go ahead and play test our game, as you can see we get the name of our account printed out.
And as you can see we also get the string of hello which we passed from the client to the server.
Again, we can pass as much information as we'd like here.
We can pass a bunch of numbers, and then here I'll just make this parameter variadic.
And then we can just print out all of those variadic results into the console.
So if I hit run.
As you can see, we get one, two, three and four, and the only limitations with sending information
through remote events are going to be tables that have mixed indexes.
So for example, you can't pass a table to the server that has a mixture of keys and also has a mixture
of indexes.
Those won't work.
And you also can't pass meta tables through remote events.
So if you had a table with a meta table attached to it, and you try to send that to the client or the
server, the table itself would be fine, but it would lose the meta table attached to it through that
transfer from the client to the server or the server to the client.
So that's just important to note.
You can't pass meta tables through remote events, and you can't pass mixed tables through remote events.
Now, another important thing you've got to be careful of is that the client can send whatever information
they want to the server.
So if you have any exploiters or hackers in your game, they can try to mess with your remote events
and cause stuff that you don't want to happen.
For example, if you ever had a tool in your game that dealt damage to other players and you made the
mistake of passing the value of how much damage you're supposed to deal to the other player, well,
if we fire this event and the server took, let's say that damage and then use that damage to apply
it on another player that can be easily exploited.
A hacker could fire this event and pass whatever number they'd like here, like a huge number to instantly
kill the other player.
So you always have to be mindful of the information that the client is passing to the server.
You got to make sure that the information is correct, and you also got to make sure that they're not
manipulating or being malicious with whatever information they're trying to send.
And you should always script your code in a way where you don't have to pass how much damage to deal
to another player through remote events that should instead be stored in some kind of property for the
tool that the server can read without having to get that information from the client.
Because, again, you never want to trust the information that is coming from the client.
You always want to verify the information because you never know if it's an exploiter trying to mess
with your game.
Now let's go ahead and also demonstrate this working in the other direction.
So if I would like the server to fire to a particular player, then what we could do is we could refer
to our event and use a function called fire client, or we could use fire all clients.
So fire client triggers an event for a particular player, while fire all clients triggers the event
for every single player that's inside of your game.
For this particular example, we're going to use fire all clients, and if you were to use the regular
fire clients, you would have to specify the player that you would like the event to trigger for.
But for fire all clients, we don't need to.
And from here we can pass whatever information we would like to our clients.
In some cases, you might not need to send any information, and in other cases you might want to send
some information like strings or numbers or whatever the case may be.
So in this case, I'm just going to send a string to the client and I'm just going to call it howdy.
And then here on our local script, what we're going to do is we're going to refer to our event, and
we're going to listen to the on client event and connect a Lambda function to this.
And then we can get the string that the server is going to pass here.
So I'll just call this example string.
And then we can go ahead and print this out into the console.
Now something you need to note is that since this server script is going to execute immediately when
we fire this event to our clients, our player may not have loaded the game yet and have and has executed
this script.
So that means the server fires this event.
But we aren't listening to it yet because this script hasn't been executed.
So to account for that, I'm going to put a delay in here.
We'll use task Dot wait and we're going to wait 10s before we fire to our player in this particular
instance.
So that gives us enough time to load into our game and then connect a function to the on client event
and listen for when we get that string passed to us.
So if we go and play test again.
As you can see, we pass information to the server and then we should wait and we should get information
passed back to the client.
Any second now.
And there we go.
Our client printed out the string that was on the server, which was howdy.
So this is how we can use remote events.
Any time you would like to listen to a remote event on the client, we use the on client event.
And any time we would like to pass information to the server from the client, we use the fire server
function.
And then here on the server, whenever we would like to listen to a remote event, we use the on server
event.
And then any time we would like to send information to players in our game, we can use the fire client
or Fire all clients function.
Okay, now let's go ahead and take a look at a remote function.
A remote function is one we use when we would like to grab or receive information from the server.
When we trigger or invoke a remote function, our script is going to yield until that remote function
returns information back to us.
This can be useful in many situations.
For example, maybe you have a door in your game that needs a special passcode.
For security reasons, you would not want to store that password on the client, but instead you would
like to store that password on the server in order to verify that the password the client enters is
correct.
We can give the server the password through a remote function, and then the server can verify if that
password is correct or not, and then it can return back to us information telling us if we got it right
or not.
There are many use cases for remote functions, however, one use case you would not want to use is
having the server invoke a client and wait for that client to send information back to the server.
This is an unreliable practice, because a player could leave the game right when the server tries to
invoke the client, which would cause the server to be stuck in an infinite yield because the player
left the game and won't send any information back to the server.
So you'll want to use remote functions for clients invoking the server, but you do not want to use
remote functions in the case of the server invoking a client.
So we can go ahead and create a new remote function inside of replicated storage.
So remote function, there we go.
And then inside of my local script I deleted everything except for our service.
And again we're going to create a variable called event.
And this time we're going to refer to our remote function.
So that's going to be equal to replicated storage dot remote function.
And what we can do here is we can refer to this event.
And we have to use a different function for this remote function.
And this function is called invoke server.
So this tells the server that we would like to execute the function attached to the on server invoke
callback.
And a callback is simply a function that's passed as an argument to another piece of code.
In this case, you would store a function in a property inside of the remote function, and that function
is expected to be executed or basically called back to execute whatever functionality we would like.
In this case, that's retrieving information from the server.
So we're going to use the invoke server function.
And let's say we have a password we would like to pass like hello.
Maybe that's the password.
And then what we're going to do in our server script is again refer to that event and replicated storage.
So our replicated storage remote function.
And this time with our remote function.
We have a property in there called on Server Invoke.
And what we have to store on this property is a function that needs to be called.
So we can auto fill in this property.
And then we assign this property with a function.
In this case we're going to create a lambda function here.
And this lambda function is also going to be passed the player that invoked this remote function.
And then we get passed any other additional information that the client has passed to us.
In this case that is our password.
And inside of here we can go ahead and store the correct password.
And let's say the correct password is howdy.
And then we can go ahead and check if the password the player passed to the server matches the correct
password.
So what we could do here is we could check if the password the player passed is equal to the correct
password.
If it is, then we can return true back to this player to let them know that hey, that was the correct
password.
Otherwise we could just return false telling them hey, the password was incorrect.
So whatever we return from this function gets sent back to our player.
So that means when we use the invoke server function, what this is going to return is whatever the
server returns back to us.
In this case we expect a boolean.
So we could call this variable result.
And that's equal to what gets returned from our invoke server function.
And then we can go ahead and print that result out inside of the console.
In this case, since our password does not match the word of howdy, we should get false printed here.
So let's go ahead and see what happens.
And as you can see, there we go.
We get false printed into the console because our password was not correct.
However, let's say we entered in the correct password, which is howdy.
Then when we go and run our game.
As you can see, we get true returned back to us, which is the server letting us know, hey, you got
the password correct?
Now.
This remote function also has a property for the client which is on client invoke.
But again, I don't recommend using this because there shouldn't be ever a circumstance where the server
would need to invoke the client, and the client has to send information back to the server.
That's just trouble waiting to happen.
I don't recommend doing it because a I can't find a use case for ever needing to do that, and b you're
going to run into problems when, let's say a player leaves your game.
So don't use on client invoke and don't invoke clients from the server.
There's no need to do that.
The main purpose of your remote functions is to get information from the server.
All righty.
You should now have a basic idea of client to server communication, and how we can use remote events
and remote functions in our scripts.
I will see you in the next lecture.